package com.chen.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chen.common.Constants;
import com.chen.common.Result;
import com.chen.common.ValidationEnum;
import com.chen.entity.Menu;
import com.chen.entity.User;
import com.chen.entity.Validation;
import com.chen.entity.bean.UserInfo;
import com.chen.mapper.RoleMapper;
import com.chen.mapper.RoleMenuMapper;
import com.chen.mapper.UserMapper;
import com.chen.mapper.ValidationMapper;
import com.chen.service.IValidationService;
import com.chen.service.LoginService;
import com.chen.service.MenuService;
import com.chen.vo.UserPasswordDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chenchao
 * @date 2022/7/17 18:44
 */
@Service
@Transactional
public class LoginServiceImpl extends ServiceImpl<UserMapper, User> implements LoginService {


    @Resource
    private RoleMapper roleMapper;

    @Resource
    private RoleMenuMapper roleMenuMapper;

    @Resource
    private MenuService menuService;

    @Resource
    private UserMapper userMapper;

    @Resource
    private JavaMailSender javaMailSender;

    @Autowired
    private IValidationService IValidationService;


    @Value("${spring.mail.username}")
    private String from;


    /**
     * 登录
     *
     * @param user
     * @return
     */
    @Override
    public Result login(User user) {
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        queryWrapper.eq("username", user.getUsername());
        queryWrapper.eq("password", user.getPassword());
        User res = userMapper.selectOne(queryWrapper);
        if (ObjectUtil.isNotEmpty(res)) {
            StpUtil.login(res.getId(), "PC");
//            获取当前登录用户的角色
            String role = res.getRole();
            List<Menu> roleMenus = getRoleMenus(role);
            res.setMenus(roleMenus);
//            List<Menu> menus = userMapper.selectUserDetail(res.getId());
//            List<Menu> pareneNode = menus.stream().filter(m -> m.getPid() == null).collect(Collectors.toList());
//            for (Menu menu : pareneNode) {
//                menu.setChildren(menus.stream().filter(m -> menu.getId().equals(m.getPid())).collect(Collectors.toList()));
//            }
//            res.setMenus(pareneNode);
//            获取token并且返回
            String token = StpUtil.getTokenValue();
            res.setToken(token);
            UserInfo info = new UserInfo(res);

            return Result.success(info);
        } else {
            return Result.error(401, "用户名或密码错误");
        }

    }



    public User getOpenid(String openid) {
        return userMapper.getOpenid(openid);
    }

    public Result login(Integer id) {
        User res = userMapper.selectById(id);

        if (ObjectUtil.isNotEmpty(res)) {
            StpUtil.login(res.getId(), "PC");
//            获取当前登录用户的角色
          /*  String role = res.getRole();
            List<Menu> roleMenus = getRoleMenus(role);
            res.setMenus(roleMenus);*/
            List<Menu> menus = userMapper.selectUserDetail(res.getId());
            List<Menu> pareneNode = menus.stream().filter(m -> m.getPid() == null).collect(Collectors.toList());
            for (Menu menu : pareneNode) {
                menu.setChildren(menus.stream().filter(m -> menu.getId().equals(m.getPid())).collect(Collectors.toList()));
            }
            res.setMenus(pareneNode);
//            获取token并且返回
            String token = StpUtil.getTokenValue();
            res.setToken(token);
            UserInfo info = new UserInfo(res);

            return Result.success(info);
        } else {
            return Result.error(401, "用户名或密码错误");
        }

    }


    /**
     * 获取当前菜单
     *
     * @param roleFlag
     * @return
     */
    private List<Menu> getRoleMenus(String roleFlag) {
        Integer roleId = roleMapper.selectByFlag(roleFlag);
        // 当前角色的所有菜单id集合
        List<Integer> menuIds = roleMenuMapper.selectByRoleId(roleId);

        // 查出系统所有的菜单(树形)
        List<Menu> menus = menuService.findMenus("");
        // new一个最后筛选完成之后的list
        List<Menu> roleMenus = new ArrayList<>();
        // 筛选当前用户角色的菜单
        for (Menu menu : menus) {
            if (menuIds.contains(menu.getId())) {
                roleMenus.add(menu);
            }
            List<Menu> children = menu.getChildren();
            // removeIf()  移除 children 里面不在 menuIds集合中的 元素
            children.removeIf(child -> !menuIds.contains(child.getId()));
        }
        return roleMenus;
    }

    @Override
    public User loginEmail(User user) {
        String email = user.getEmail();
        String code = user.getCode();
        user.setUsername(email);
        user.setRole("ROLE_USER");
        user.setNickname("游客");
        user.setAddress("地球");
        user.setEmail(email);
        user.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        userMapper.insert(user);
        return null;

    }

    @Override
    public void sendEmail(String email) {
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setSubject("【personcoder】 注册验证码");
//        随机4位长度的验证码
        String code = RandomUtil.randomNumbers(4);
        System.out.println(code);
        mailMessage.setText("您本次注册邮箱验证码是:" + code + ",有效期5分钟，请妥善保管，请勿泄露");
        mailMessage.setFrom(from);
        mailMessage.setTo(email);
        Date now = new Date();

        IValidationService.saveCode(email, code, ValidationEnum.LOGIN.getCode(), DateUtil.offsetMinute(now, 5));
        javaMailSender.send(mailMessage);
    }


//    忘记密码
@Override
public Result updatePassword(UserPasswordDTO userPasswordDTO) {
    int update = userMapper.updatePassword(userPasswordDTO);
    if (update < 1) {
        return Result.error(401,"更新失败");
    }
    return Result.success();
}

    public  String buildUrl(String host, String path, Map<String, Object> querys) throws
            UnsupportedEncodingException {
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append(host).append(path);

        StringBuilder sbQuery = new StringBuilder();

        for (Map.Entry<String, Object> query : querys.entrySet()) {
            if (sbQuery.length() > 0) {
                sbQuery.append("&");
            }
            sbQuery.append(query.getKey());
            sbQuery.append("=");
            sbQuery.append(URLEncoder.encode(query.getValue().toString(), "utf-8"));
        }

        if (sbQuery.length() > 0) {
            sbUrl.append("?").append(sbQuery);
        }

        return sbUrl.toString();
    }

}
